package com.ruoyi.community.interceptor;


import com.alibaba.druid.support.json.JSONUtils;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.community.constant.ConfigConstant;
import com.ruoyi.community.constant.CommonConstants;
import com.ruoyi.community.constant.WxMaConstants;
import com.ruoyi.community.domain.User;
import com.ruoyi.community.service.IUserService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * ThirdSession拦截器，校验每个请求的ThirdSession
 * @author
 * HandlerInterceptorAdapter 自定义拦截器
 */
@Slf4j
@Component
@AllArgsConstructor
public class ThirdSessionInterceptor implements HandlerInterceptor {

	private IUserService userService;

	private final RedisTemplate redisTemplate;

	 /**
	  * preHandle方法是进行处理器拦截用的，顾名思义，该方法将在Controller处理之前进行调用。
	  * SpringMVC中的Interceptor拦截器是链式的，可以同时存在多个Interceptor，
	  * 然后SpringMVC会根据声明的前后顺序一个接一个的执行，
	  * 而且所有的Interceptor中的preHandle方法都会在Controller方法调用之前调用。
	  *
	  * Revision Trail: (Date/Author/Description)
	  * 2021/12/28 lj CREATE
	  * @author LuoYi
	  */
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//获取header中的appid
		String appid = request.getHeader(ConfigConstant.TOKEN_OPENID);
		if(StringUtils.isNotBlank(appid)){
			//获取缓存中的appid
			String key = WxMaConstants.TOKEN_OPENID_BEGIN  + ":" + appid;
			Object wxUser = redisTemplate.opsForValue().get(key);
			if(wxUser == null) {
				User user=new User();
				user.setWeixinOpenid(appid);
				List<User> us = userService.selectUserList(user);
				if(us!=null && us.size()>0){
					redisTemplate.opsForValue().set(WxMaConstants.TOKEN_OPENID_BEGIN+":"+appid,us.get(0),10, TimeUnit.HOURS);
					return Boolean.TRUE;
				}else{
				AjaxResult r = AjaxResult.error( "系统错误，请稍候再试");
				this.writerPrint(response, r);
					return Boolean.FALSE;
				}
			}else {
				return Boolean.TRUE;
			}
		}else{
			AjaxResult r = AjaxResult.error("appid不能为空");
 		    this.writerPrint(response, r);
			return Boolean.FALSE;
		}
	//	return Boolean.TRUE;
	}
 /**
  * response.getWriter()返回的是PrintWriter，这是一个打印输出流
  *
  * response.getWriter().write(）和 response.getWriter().print(）是响应给客户端的东西，如果不用ajax接收将数据放在合适的位置，就会在浏览器上生成一个新的页面来显示内容。
  *
  * print
  * response.getWriter().print(),不仅可以打印输出文本格式的（包括html标签），还可以将一个对象以默认的编码方式转换为二进制字节输出
  *
  * writer
  * response.getWriter().writer(),只能打印输出文本格式的（包括html标签），不可以打印对象
  *
  * Revision Trail: (Date/Author/Description)
  * 2021/12/28 LuoYi CREATE
  * @author LuoYi
  */
	private void writerPrint(HttpServletResponse response, AjaxResult r) throws IOException {
		//返回超时错误码
		response.setCharacterEncoding(CommonConstants.UTF8);
		response.setContentType(MediaType.APPLICATION_JSON_VALUE);
		PrintWriter writer = response.getWriter();
		writer.print(JSONUtils.toJSONString(r));
		if(writer != null){
			writer.close();
		}
	}


}
